import [Value,Scope,Symbol,Errors,Macro]
import structs/[ArrayList,HashMap]

Function : class extends Value {
    name : String
    args : ArrayList<Symbol>
    body : Value
    
    init : func ~withoutLine (=name,=args,=body)
    init : func ~withLine (=name,=args,=body,=line)
    
    toString : func -> String { name }
    
    equals? : func(other : Value) -> Bool {
        other class == This && other as Function name == this name && other as Function args == this args && other as Function body == this body
        // Make sure the functions are completely equal (all anymous functions have the same name :/)
    }
    
    call : func(arguments : ArrayList<Value>, decorativeScope : Scope) -> Value {
        scope := Scope new()
        scope parent = decorativeScope
    
        if(arguments size != args size) { //Make sure the correct amount of parameters passed to the function
            ArgumentsNotEqualToError new(name,args size,arguments size,line) throw()
        }
        for(i in 0 .. arguments size) { //Set the parameters to their values
            scope[args[i] name] = arguments[i] evaluate(decorativeScope)
        }
    
        body evaluate(scope)
    }
}